package top.saodisheng.vo;

import java.io.IOException;
import java.io.Serializable;
import java.util.*;

import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import top.saodisheng.enums.ExceptionEnums;
import top.saodisheng.utils.JacksonUtil;

/**
 * description:
 *
 * @author saodisheng
 * @date 2022/8/1
 */
public class RestResponse<T> extends HashMap<String, Object> implements Serializable {
    private static final int COMMON_SUCCESS_CODE = 200;
    private static final int COMMON_ERROR_CODE = 500;

    public RestResponse(int code, boolean success, String subCode, String message, T data) {
        this.setAny("code", code);
        this.setAny("success", success);
        this.setAny("subCode", subCode);
        this.setAny("message", message);
        this.setAny("data", data);
    }

    public static <T> RestResponse ok() {
        return ok(null);
    }

    public static <T> RestResponse ok(T data) {
        return new RestResponse(COMMON_SUCCESS_CODE, true, "", "", data);
    }

    public static <T> RestResponse error(int code, String subCode, String message, T data) {
        return new RestResponse(code, false, subCode, message, data);
    }

    public static <T> RestResponse error(String message) {
        return error(COMMON_ERROR_CODE, message);
    }

    public static <T> RestResponse error(int code, String message) {
        return error(code, "", message, null);
    }

    public static <T> RestResponse error(BindingResult bindingResult) {
        return error(getJsonString(bindingResult));
    }

    public static <T> RestResponse error(ExceptionEnums enums, Object... args) {
        return error(enums.getCode(), enums.getSubCode(), String.format(enums.getMsg(), args), null);
    }

    public Boolean isOk() {
        return this.myGet("success", Boolean.class);
    }

    public Object getData() {
        return this.myGet("data", Object.class);
    }

    public String getMessage() {
        return this.myGet("message", String.class);
    }

    public RestResponse setAny(String key, Object value) {
        if (key != null && value != null) {
            this.put(key, value);
        }
        return this;
    }

    private <T> T myGet(String key, Class<T> type) {
        Object obj = this.get(key);
        return Objects.isNull(obj) ? null : (T) obj;
    }

    public static String getJsonString(BindingResult bindingResult) {
        if (bindingResult.getAllErrors().size() == 0) {
            return "";
        } else {
            List<ErrorInfo> errorInfoList = new ArrayList<>();
            Iterator<FieldError> var3 = bindingResult.getFieldErrors().iterator();

            while (var3.hasNext()) {
                FieldError error = var3.next();
                ErrorInfo errorInfo = new ErrorInfo();
                errorInfo.setField(error.getField());
                errorInfo.setInfo(error.getDefaultMessage());
                errorInfo.setType(error.getCode());
                errorInfoList.add(errorInfo);
            }

            String myInfo = null;

            try {
                myInfo = JacksonUtil.toJson(errorInfoList);
            } catch (IOException var5) {
                var5.printStackTrace();
            }

            return myInfo;
        }
    }

    public int getCode() {
        return this.myGet("code", Integer.class);
    }

    public String getSubCode() {
        return this.myGet("subCode", String.class);
    }

    public void setSubCode(String subCode) {
        this.setAny("subCode", subCode);
    }

    public RestResponse setData(T data) {
        this.put("data", data);
        return this;
    }
}
